
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta charset="utf-8"></meta>
      <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
      <title>Chapter&nbsp;15.&nbsp;Graph Refactoring - APOC User Guide 3.4</title>
      <link rel="stylesheet" type="text/css" href="../docbook.css"></link>
      <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,400italic,600,300italic"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/theme/neo.min.css"></link>
      <link rel="stylesheet" type="text/css" href="../css/chunked-base.css"></link>
      <link rel="stylesheet" type="text/css" href="../css/extra.css"></link><script src="//code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script><script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js" type="text/javascript"></script><script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/addon/runmode/runmode.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/mode/cypher/cypher.min.js" type="text/javascript"></script><script src="../javascript/datatable.js" type="text/javascript"></script><script src="../javascript/colorize.js" type="text/javascript"></script><script src="../javascript/tabs-for-chunked.js" type="text/javascript"></script><script src="../javascript/mp-nav.js" type="text/javascript"></script><script src="../javascript/versionswitcher.js" type="text/javascript"></script><script src="../javascript/version.js" type="text/javascript"></script><script src="//s3-eu-west-1.amazonaws.com/alpha.neohq.net/docs/new-manual/assets/search.js" type="text/javascript"></script><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"></meta>
      <link rel="prev" href="../virtual/graph-grouping/" title="14.6.&nbsp;Graph Grouping"></link>
      <link rel="next" href="clone-nodes/" title="15.1.&nbsp;Clone nodes"></link>
      <link rel="shortcut icon" href="https://neo4j.com/wp-content/themes/neo4jweb/favicon.ico"></link><script>
        $(document).ready(function() {
          CodeMirror.colorize();
          tabTheSource($('body'));
          var $header = $('header').first();
          $header.prepend(
            $('<a href="" id="logo"><img src="https://neo4j.com/wp-content/themes/neo4jweb/assets/images/neo4j-logo-2015.png" alt="Neo4j Logo"></img></a>')
          );
          var $sidebar = $('<div id="sidebar-wrapper"></div>');
          $.get('toc.html', function (d){
            $(d).appendTo($sidebar);
            highlightToc();
            highlightLibraryHeader();
          });
          $sidebar.insertAfter($('header').first());
        });
        </script></head>
   <body>
      <header>
         <div class="searchbox">
            <form id="search-form" class="search" name="search-form" role="search"><input id="search-form-input" name="q" title="search" type="search" lang="en" placeholder="Search Neo4j docs..." aria-label="Search Neo4j documentation" max-length="128" required="required"></input><input id="search-form-button" type="submit" value="Search"></input></form>
         </div>
         <ul class="documentation-library">
            <li><a href="https://neo4j.com/docs/operations-manual/current">Operations Manual</a></li>
            <li><a href="https://neo4j.com/docs/developer-manual/current/">Developer Manual</a></li>
            <li><a href="https://neo4j.com/docs/ogm-manual/current/">OGM Manual</a></li>
            <li><a href="https://neo4j.com/docs/graph-algorithms/current/">Graph Algorithms</a></li>
            <li><a href="https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.4/">APOC</a></li>
            <li><a href="https://neo4j.com/docs/java-reference/current/">Java Reference</a></li>
         </ul>
         <nav id="header-nav"><span class="nav-previous"><a accesskey="p" href="../virtual/graph-grouping/"><span class="fa fa-long-arrow-left" aria-hidden="true"></span>Graph Grouping</a></span><span class="nav-current">
               <p class="nav-title hidden">Chapter&nbsp;15.&nbsp;Graph Refactoring</p></span><span class="nav-next"><a accesskey="n" href="clone-nodes/">Clone nodes<span class="fa fa-long-arrow-right" aria-hidden="true"></span></a></span></nav>
      </header>
      <div id="search-results" class="hidden"></div>
      <section class="chapter" id="graph-refactoring">
         <div class="titlepage">
            <div>
               <div>
                  <h1 class="title">Chapter&nbsp;15.&nbsp;Graph Refactoring</h1>
               </div>
            </div>
         </div>
         <div class="informaltable">
            <div class="table" id="d0e18418">
               <table class="informaltable" border="1">
                  <colgroup>
                     <col class="col_1"></col>
                     <col class="col_2"></col>
                  </colgroup>
                  <tbody>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.cloneNodes([node1,node2,&#8230;&#8203;])</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>clone nodes with their labels and properties</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.cloneNodesWithRelationships([node1,node2,&#8230;&#8203;])</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>clone nodes with their labels, properties and relationships</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.cloneSubgraph([node1,node2,&#8230;&#8203;], [rel1,rel2,&#8230;&#8203;]=[], {standinNodes:[[oldNode1, standinNode1], &#8230;&#8203;], skipProperties:[prop1,
                                 prop2, &#8230;&#8203;]}={}) YIELD input, output, error</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>clone nodes with their labels and properties (optionally skipping any properties in the skipProperties list via the config
                              map), and clone the given relationships (will exist between cloned nodes only). If no relationships are provided, all relationships
                              between the given nodes will be cloned. Relationships can be optionally redirected according to standinNodes node pairings
                              (this is a list of list-pairs of nodes), so given a node in the original subgraph (first of the pair), an existing node (second
                              of the pair) can act as a standin for it within the cloned subgraph. Cloned relationships will be redirected to the standin.
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.cloneSubgraphFromPaths([path1,path2,&#8230;&#8203;], {standinNodes:[[oldNode1, standinNode1], &#8230;&#8203;], skipProperties:[prop1,
                                 prop2, &#8230;&#8203;]}={}) YIELD input, output, error</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>from the subgraph formed from the given paths, clone nodes with their labels and properties (optionally skipping any properties
                              in the skipProperties list via the config map),
                              and clone the relationships (will exist between cloned nodes only). Relationships can be redirected according to optional
                              standinNodes node pairings (this is a list of list-pairs of nodes), so given a node in the original subgraph (first of the
                              pair), an existing node (second of the pair) can act as a standin for it within the cloned subgraph. Cloned relationships
                              will be redirected to the standin.
                           </p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.mergeNodes([node1,node2])</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>merge nodes onto first in list</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.mergeRelationships([rel1,rel2,&#8230;&#8203;],{config})</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>merge relationships onto first in list</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.to(rel, endNode)</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>redirect relationship to use new end-node</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.from(rel, startNode)</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>redirect relationship to use new start-node</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.invert(rel)</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>inverts relationship direction</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.setType(rel, 'NEW-TYPE')</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>change relationship-type</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.extractNode([rel1,rel2,&#8230;&#8203;], [labels], 'OUT','IN')</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>extract node from relationships</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.collapseNode([node1,node2],'TYPE')</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>collapse nodes with 2 rels to relationship, node with one rel becomes self-relationship</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.normalizeAsBoolean(entity, propertyKey, true_values, false_values)</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>normalize/convert a property to be boolean</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">call apoc.refactor.categorize(node, propertyKey, type, outgoing, label)</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>turn each unique propertyKey into a category node and connect to it</p>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </div>
         </div>
         <p>On mergeRelationship and mergeNodes with config properties you can choose from 3 different management:
             * "overwrite" or "override": if there is the same property in more relationship, in the new one will have the last relationship&#8217;s
            property value
             * "discard" : if there is the same property in more relationship, the new one will have the first relationship&#8217;s property
            value
             * "combine" : if there is the same property in more relationship, the new one a value&#8217;s array with all relationships' values
         </p>
         <p>On mergeNodes procedure there is also a config parameter to merge relationships of the merged nodes:
             * "mergeRels: true/false" : give the possibility to merge relationships with same type and direction.
         </p>
         <p>If relationships have same start and end nodes will be merged into one, and properties managed by the properties config.
            If relationships have different start/end nodes (related to direction), relationships will be maintained and properties will
            be combine in all relationship.
         </p>
         <section class="section" id="_normalize_as_boolean">
            <div class="titlepage">
               <div>
                  <div>
                     <h2 class="title" style="clear: both"><a class="anchor" href="#_normalize_as_boolean"></a>15.9.&nbsp;Normalize As Boolean
                     </h2>
                  </div>
               </div>
            </div><pre class="programlisting highlight"><code data-lang="cypher">CREATE (:Person {prop: 'Y', name:'A'}),(:Person {prop: 'Yes', name:'B'}),(:Person {prop: 'NO', name:'C'}),(:Person {prop: 'X', name:'D'})</code></pre><p>As a resul we have four nodes with different properties <code class="literal">prop</code> like <code class="literal">Y</code>, <code class="literal">Yes</code>, <code class="literal">NO</code>, <code class="literal">X</code></p>
            <div class="informalfigure">
               <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.normalizeAsBoolean.dataset.png" width="800" alt="apoc.refactor.normalizeAsBoolean.dataset"></img></div>
            </div>
            <p>Now we want to transform some properties into a boolean, <code class="literal">Y</code>, <code class="literal">Yes</code> into true and the properties <code class="literal">NO</code> into false.
               The other properties that don&#8217;t match these possibilities will be set as <code class="literal">null</code>.
            </p><pre class="programlisting highlight"><code data-lang="cypher">MATCH (n)  CALL apoc.refactor.normalizeAsBoolean(n,'prop',['Y','Yes'],['NO']) WITH n ORDER BY n.id RETURN n.prop AS prop</code></pre><div class="informalfigure">
               <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.refactor.normalizeAsBoolean.png" width="800" alt="apoc.refactor.normalizeAsBoolean"></img></div>
            </div>
         </section>
         <section class="section" id="_using_cypher_and_apoc_to_move_a_property_value_to_a_label">
            <div class="titlepage">
               <div>
                  <div>
                     <h2 class="title" style="clear: both"><a class="anchor" href="#_using_cypher_and_apoc_to_move_a_property_value_to_a_label"></a>15.11.&nbsp;Using Cypher and APOC to move a property value to a label
                     </h2>
                  </div>
               </div>
            </div>
            <p>You can use the procedure <code class="literal">apoc.create.addLabels</code> to move a property to a label with Cypher as follows
            </p>
            <p><span class="formalpara-title">Create a node with property studio.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">CREATE (:Movie {title: 'A Few Good Men', genre: 'Drama'})</code></pre><p>
               
            </p>
            <p><span class="formalpara-title">Move the 'genre' property to a label and remove it as a property.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">MATCH (n:Movie)
CALL apoc.create.addLabels( id(n), [ n.genre ] ) YIELD node
REMOVE node.genre
RETURN node</code></pre><p>
               
            </p>
         </section>
      </section>
      <footer><script type="text/javascript">
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
          //Allow Linker
          ga('create', 'UA-1192232-34','auto', {'allowLinker': true});
          ga('send', 'pageview');
          // Load the plugin.
          ga('require', 'linker');
          // Define which domains to autoLink.
          ga('linker:autoLink', ['neo4j.org','neo4j.com','neotechnology.com','graphdatabases.com','graphconnect.com']);
        </script><script type="text/javascript">
          document.write(unescape("%3Cscript src='//munchkin.marketo.net/munchkin.js' type='text/javascript'%3E%3C/script%3E"));
        </script><script>Munchkin.init('773-GON-065');</script></footer>
   </body>
</html>